/**
 * jsonp原理：前端构造script标签，和一个数据接受函数f; 然后设置src的值并将其插入到文档中去，以此发送一个绕过跨域检测的get请求；服务器收到这种get请求之后，根据get请求传递的信息（函数f名），将准备好的数据作为调用此约定函数的形参，并将函数调用作为字符串原码写在将要返回的脚本文件中；当script标签加载完毕之后，返回的脚本文件会自动执行，此时数据就通过预设函数f被转发到正确的位置（或被预定操作处理）。
用一句话来概括一下：将本来通过接口访问的信息通过js脚本来传递，然后通过函数调用的方法将js脚本中的信息取出来。
实际上，数据接受函数f不是重点，重点是将数据写在js脚本中，如下所示

 * @param {*} url 
 * @param {*} params 
 * @returns 
 */
function jsonP(url, params) {
  return new Promise((resolve, reject) => {
    const callbackName = "jsonPCallBack" + Date.now();
    const _script = document.createElement("script");

    // 全局方法
    window[callbackName] = function (data) {
      document.body.removeChild(_script);
      // 完成后移除
      delete window[callbackName];
      resolve(data);
    };

    // 接下来进行查询参数的序列化
    let _arr = [];
    for (let key in params) {
      if (params.hasOwnProperty(key)) {
        _arr.push(`${key}=${params[key]}`);
      }
    }
    if (_arr.length) {
      _arr.unshift("");
    }
    // 设置动态标签的类型
    _script.type = "text/javascript";
    // 设置动态标签的地址
    _script.src = `${url}?callback=${callbackName}${_arr.join("&")}`;

    document.body.appendChild(script);
  });
}
